﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;

using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swcommands;
using SolidWorks.Interop.swconst;
using SolidWorks.Interop.swpublished;

using SwAddinHelpers.Contracts;
using SwAddinHelpers.Attributes;
using SwAddinHelpers.Base;

namespace SwAddinHelpers.PropertyManager
{
    public sealed class PropertyManagerHost: UserControlHostBase
    {
        // DUPLICATE CALLBACKS
        // Uncomment the above named section to see how host and control sinks operate together
        //[SinkMethod(SwAddinHelpers.Sinks.enumEventSink.SW_ActiveModelDocChangeNotify, true)]
        //public void SomeMethodToFire(object sender, EventArgs e)
        //{
        //   OwnerAddin.Debug.Manager.PostEvent(SwAddinHelpers.AddinManager.enumDebugMsgType.UserExecution3, "pmp host");
        //}
        
        private PropertyManagerHandler _PropertyManagerHandler;

        public PropertyManagerHandler PropertyManagerHandler
        {
            get { return _PropertyManagerHandler; }
        }

        private PropertyManagerPage2 _PropertyManagerView;

        public PropertyManagerPage2 PropertyManagerView
        {
            get { return _PropertyManagerView; }
        }

        private PropertyManagerPageActiveX _PropertyManagerControlActiveX;

        public PropertyManagerPageActiveX PropertyManagerControlActiveX
        {
            get { return _PropertyManagerControlActiveX; }
        }

        private bool _isHosted;

        public PropertyManagerHost(ISwAddinBase owner, IExternalUserControl externalControl, string Title,
                                   string ControlCaption, string ControlToolTip, int options, bool IsHosted = false )
        {
            _isHosted = IsHosted;
            
            _OwnerAddin = owner;

            base.externalControl = externalControl.ExternalUserControl;
            _HostedControlId = GetControlId();

            int errors = -1;
            //int warnings = -1;
            
            //int options = (int)swPropertyManagerPageOptions_e.swPropertyManagerOptions_OkayButton |
            //    (int)swPropertyManagerPageOptions_e.swPropertyManagerOptions_CancelButton;

            _PropertyManagerHandler = new PropertyManagerHandler(this);
            _PropertyManagerView = (PropertyManagerPage2)_OwnerAddin.SolidWorksApplication.CreatePropertyManagerPage(Title, options, _PropertyManagerHandler, ref errors);

            if (_PropertyManagerView != null && errors == (int)swPropertyManagerPageStatus_e.swPropertyManagerPage_Okay)
            {
                short controlType = (int)swPropertyManagerPageControlType_e.swControlType_ActiveX;
                short align = (int)swPropertyManagerPageControlLeftAlign_e.swControlAlign_LeftEdge;
                options = (int)swAddControlOptions_e.swControlOptions_Enabled |
                          (int)swAddControlOptions_e.swControlOptions_Visible;

                _PropertyManagerControlActiveX = (PropertyManagerPageActiveX)_PropertyManagerView.AddControl(_HostedControlId, controlType, ControlCaption , align, options, ControlToolTip);
                short[] size = GetPreDefinedControlSize();
                _PropertyManagerControlActiveX.Height = size[1];
                ((PropertyManagerPageControl)_PropertyManagerControlActiveX).Width = size[0];
                _PropertyManagerControlActiveX.SetClass(HostedControlTypeProgId, "");

                // Try to open the dummy document and show/close the PMP.  
                // This will force the PMP to create the ActiveX control and subscribe to events right away.

                #region OpenDoc7 Implementation
                try
                {
                    DocumentSpecification docspec = (DocumentSpecification)_OwnerAddin.SolidWorksApplication.GetOpenDocSpec(_OwnerAddin.DUMMYFILE);
                    docspec.Silent = true;
                    ModelDoc2 doc2 = _OwnerAddin.SolidWorksApplication.OpenDoc7(docspec);

                    _PropertyManagerView.Show2(-1);  // ActiveX creation occurs here.
                    _PropertyManagerView.Close(false);

                    _OwnerAddin.SolidWorksApplication.CloseDoc(docspec.FileName);
                    //_OwnerAddin.SolidWorksApplication.CloseAllDocuments(true);
                    Marshal.ReleaseComObject(doc2);
                    doc2 = null;

                    if (docspec.Error > 0)
                        IsLateSubscriber = true;
                    else
                        IsLateSubscriber = false;

                    if (IsControlCreated) IsLateSubscriber = false;
                }
                catch
                {
                    IsLateSubscriber = true;
                }
                #endregion

                #region OpenDoc6 Implementation
                /*
                try
                {
                    ModelDoc2 doc = _OwnerAddin.SolidWorksApplication.OpenDoc6(
                        _OwnerAddin.DUMMYFILE,
                        (int)swDocumentTypes_e.swDocPART,
                        (int)swOpenDocOptions_e.swOpenDocOptions_Silent,
                        null,
                        ref errors,
                        ref warnings);

                    _PropertyManagerView.Show2(-1);
                    _PropertyManagerView.Close(false);

                    _OwnerAddin.SolidWorksApplication.CloseAllDocuments(true);
                    Marshal.ReleaseComObject(doc);
                    doc = null;

                    if (errors > 0)
                        IsLateSubscriber = true;
                    else
                        IsLateSubscriber = false;

                    if (IsControlCreated) IsLateSubscriber = false;
                }
                catch
                {
                    IsLateSubscriber = true;
                }
                */
                #endregion
            }

            // DUPLICATE CALLBACKS
            //SubscribeEvent(Sinks.enumEventSink.SW_ActiveModelDocChangeNotify, enumEventSubscriptionSource.GUI_HOST);
        }

        public override void Teardown()
        {
            base.Teardown();

            try { Marshal.ReleaseComObject(_PropertyManagerControlActiveX.GetControl()); }
            catch { }

            Marshal.ReleaseComObject(_PropertyManagerControlActiveX);
            _PropertyManagerControlActiveX = null;
            
            Marshal.ReleaseComObject(_PropertyManagerView);
            _PropertyManagerView = null;

            _PropertyManagerHandler = null;
        }

        public void Show()
        {
            if (_isHosted)
            {
                // activate the correct feature view PMP holder first
                //((SwAddinHelpers.FeatureView.FeatureViewHost)_OwnerHost.OwnerAddin.RetrieveUIHostByProgId("SwExternalControls.ExternalFeatureViewTemplateControl1")).ActivatePmpHolder();
                _OwnerAddin.ActivatePropertyPageHost();
            }
            
            _PropertyManagerView.Close(false);
            _PropertyManagerView.Show2(0);
        }
    }
}
